package com.ulk.systempermission;

import android.content.Intent;
import android.os.IBinder;
import android.text.TextUtils;

import com.suyoung.systemset.SystemSetting;
import com.ulk.common_interface.Define;
import com.ulk.common_interface.utils.KeyUtils;
import com.ulk.corelib.base.BaseService;
import com.ulk.corelib.db.Packet;
import com.ulk.corelib.utils.apk.ApkUtils;
import com.ulk.corelib.utils.log.LogUtils;
import com.ulk.corelib.utils.shell.ShellUtils;
import com.ulk.systempermission.utils.DateTimeUtils;
import com.ulk.systempermission.utils.PowerUtils;
import com.ulk.systempermission.utils.ProcessUtils;
import com.ulk.systempermission.utils.RebootUtils;
import com.ulk.systempermission_interface.SystemPermissionDefine;
import com.ulk.systempermission_interface.SystemPermissionInterface;

/**
 * the system permission service.
 *
 * @author xuxiaohong
 * @date 2016/4/25
 */
public class SystemPermissionService extends BaseService {

    /**TAG*/
    private static final String TAG = "SystemPermissionService";

    @Override
    public String getMessageType() {
        return SystemPermissionDefine.MODULE;
    }

    public SystemPermissionService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();

        // -----------------------------------
        // Set the priority of the calling thread, based on Linux priorities:
        // -----------------------------------
        // The Priority.
        final int priority = android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY;//THREAD_PRIORITY_FOREGROUND;
        // Changes the Priority of the calling Thread!
        android.os.Process.setThreadPriority(priority);
        // Changes the Priority of passed Thread (first param)
        android.os.Process.setThreadPriority(android.os.Process.myTid(), priority);

        DateTimeUtils.newInstance(this);

        // 开机在唤醒
        PowerUtils.wakeupFromDeepSleep(this, null);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public Packet dispatch(int nId, Packet packet) {
        Packet ret =  super.dispatch(nId, packet);
        switch (nId) {
            case SystemPermissionInterface.MAIN_TO_APK.GOTO_DEEP_SLEEP:
                PowerUtils.goToDeepSleep(this, packet);
                break;
            case SystemPermissionInterface.MAIN_TO_APK.WAKEUP_FROM_DEEP_SLEEP:
                PowerUtils.wakeupFromDeepSleep(this, packet);
                break;

            case SystemPermissionInterface.MAIN_TO_APK.LOCALE:
                if (packet != null) {
                    String language = packet.getString(SystemPermissionDefine.ParseKey.LOCALE);
                    if (null != language) {
                        if (language.equals(Define.Language.Default.name())) {
                            //Main请求默认语言
                            com.ulk.systempermission.SystemPermissionDefine.Language defLanguage =
                                    com.ulk.systempermission.SystemPermissionDefine.Language.valueOf(getResources().getConfiguration().locale);
                            if (null != defLanguage) {
                                Packet pak = new Packet();
                                pak.putString(SystemPermissionDefine.ParseKey.LOCALE, defLanguage.name());
                                Notify(false, SystemPermissionInterface.APK_TO_MAIN.LOCALE, pak);
                            }
                        } else {
                            //设置语言
                            try {
                                com.ulk.systempermission.SystemPermissionDefine.Language setLanguage =
                                        com.ulk.systempermission.SystemPermissionDefine.Language.valueOf(language);

                                Packet pak = new Packet();
                                pak.putString(SystemPermissionDefine.ParseKey.LOCALE, language);
                                Notify(false, SystemPermissionInterface.APK_TO_MAIN.LOCALE, pak);

                                final SystemSetting systemSetting = new SystemSetting(this);
                                systemSetting.setLanguage(setLanguage.locale());
                            } catch (IllegalArgumentException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                break;

            case SystemPermissionInterface.MAIN_TO_APK.TIME_SET:
                if (packet != null) {
                    String resource = packet.getString(Define.Time.RESOURCE);
                    if (Define.Time.SRC_GPS.equals(resource)) {
                        DateTimeUtils.getInstance().setTimeResource(DateTimeUtils.TimeSource.GPS, packet);
                    } else if (Define.Time.SRC_NET.equals(resource)) {
                        DateTimeUtils.getInstance().setTimeResource(DateTimeUtils.TimeSource.NET, packet);
                    } else if (Define.Time.SRC_MANU.equals(resource)) {
                        DateTimeUtils.getInstance().setTimeResource(DateTimeUtils.TimeSource.MANU, packet);
                    }  else if (Define.Time.SRC_SMART.equals(resource)) {
                        DateTimeUtils.getInstance().setTimeResource(DateTimeUtils.TimeSource.SMART, packet);
                    }
                }
                break;

            case SystemPermissionInterface.MAIN_TO_APK.TIME_FORMAT:
                if (packet != null) {
                    DateTimeUtils.getInstance().setTimeFormat(this, packet.getString(Define.Time.FORMAT));
                }
                break;

            case SystemPermissionInterface.MAIN_TO_APK.FACTORY_MODULES_INIT:
                if (packet != null) {
                    Packet init = new Packet();
                    /**收到模块名称-包名*/
                    for (Define.Factory.Modules modules : Define.Factory.Modules.values()) {
                        if (modules != null) {
                            String apkName = packet.getString(modules.value());
                            if (apkName != null) {
                                boolean enable = ApkUtils.getPacketEnable(getApplicationContext(), apkName);
                                LogUtils.d("FactoryModules", modules.value() + " " + apkName + " " + enable);
                                init.putBoolean(modules.value(), enable);
                            }
                        }
                    }
                    /**收到模块名称-使能值*/
                    Notify(false, SystemPermissionInterface.APK_TO_MAIN.FACTORY_MODULES_INIT, init);
                }
                break;

            case SystemPermissionInterface.MAIN_TO_APK.FACTORY_MODULES:
                if (packet != null) {
                    try {
                        Define.Factory.Modules modules = Define.Factory.Modules.valueOf(packet.getString(Define.Factory.MODULE));
                        String packetName = packet.getString("PacketName");
                        if (packetName != null) {
                            boolean enable = packet.getBoolean(modules.value());
                            LogUtils.d("FactoryModules", modules.value() + " " + packetName + " " + enable);
                            if (!ApkUtils.setEnable(getApplicationContext(), packetName, enable)) {
                                Packet result = new Packet();
                                result.putString(Define.Factory.MODULE, modules.value());
                                enable = ApkUtils.getPacketEnable(getApplicationContext(), packetName);
                                result.putBoolean(modules.value(), enable);
                                Notify(false, SystemPermissionInterface.APK_TO_MAIN.FACTORY_MODULES, result);
                            }
                        }
                    } catch (IllegalArgumentException e) {

                    }
                }
                break;

            case SystemPermissionInterface.MAIN_TO_APK.SIMULATE_KEY:
                if (null != packet) {
                    final int key = packet.getInt("key", Define.Key.KEY_NONE);
                    if (Define.Key.KEY_NONE != key) {
                        int code = KeyUtils.app2android(key);
                        execShellCommand("input keyevent " + code, false);
                    }
                }
                break;

            case SystemPermissionInterface.MAIN_TO_APK.EXEC_SHELL_COMMAND:
                if (null != packet) {
                    final String command = packet.getString("command");
                    final boolean isRoot = packet.getBoolean("isRoot", false);
                    execShellCommand(command, isRoot);
                }
                break;

            case SystemPermissionInterface.MAIN_TO_APK.RESTOR_FACTORY_SETTINGS:
                RebootUtils.rebootRestoreFactorySettings(getApplicationContext());
                break;

            case SystemPermissionInterface.MAIN_TO_APK.WIPE_USER_DATA:
                RebootUtils.rebootWipeUserData(getApplicationContext());
                break;

            case SystemPermissionInterface.MAIN_TO_APK.WIPE_CACHE:
                RebootUtils.rebootWipeCache(getApplicationContext());
                break;

            case SystemPermissionInterface.MAIN_TO_APK.OS_UPDATE:
                execShellCommand("echo \"--update_package=/sdcard/update.zip\" > /cache/recovery/command", false);
                execShellCommand("reboot recovery", false);
                break;

            case SystemPermissionInterface.MAIN_TO_APK.KILL_PROCCESS:
                if (null != packet) {
                    final String pkgName = packet.getString("pkgName");
                    if (!TextUtils.isEmpty(pkgName)) {
                        ProcessUtils.killProcess(this, pkgName);
                    } else {
                        LogUtils.d(TAG, "Kill process failed, because the pkgName = " + pkgName);
                    }
                }
                break;
            default:
                break;
        }
        return ret;
    }

    /**执行shell命令*/
    private void execShellCommand(String command, boolean isRoot) {
        if (!TextUtils.isEmpty(command)) {
            ShellUtils.CommandResult sc = ShellUtils.execCommand(command, isRoot, true);
            LogUtils.d(TAG, "sc.successMsg = " + sc.successMsg + " sc = errorMsg" + sc.errorMsg + " result = " + sc.result);
        }
    }
}
